package com.example.byexample

fun main() {
    // 控制流
    // When

    // When Statement
    cases("Hello")
    cases(1)
    cases(0L)
    cases(MyClass())
    cases("hello")

    // When Expression
    println(whenAssign("Hello"))
    println(whenAssign(3.4))
    println(whenAssign(1))
    println(whenAssign(MyClass()))

    // Loops
    val cakes = listOf<String>("carrot", "cheese", "chocolate")
    for (cake in cakes) {
        println("Yummy, it's a $cake cake!")
    }

    var cakesEaten = 0
    var cakesBaked = 0

    while (cakesEaten < 5) { // 在条件为真时执行块。
        eatACake()
        cakesEaten++
    }

    do { // 首先执行块，然后检查条件。
        bakeACake()
        cakesBaked++
    } while (cakesBaked < cakesEaten)

    // 迭代器
    // 在类中实现迭代器运算符
    val zoo = Zoo(listOf(Animal("zebra"), Animal("lion")))

    for (animal in zoo) {
        println("Watch out, it's a ${animal.name}")
    }

    // Ranges 范围
    for (i in 0..3) {
        print(i)
    }
    print(" ")

    for (i in 0 until 3) {
        print(i)
    }
    print(" ")

    for (i in 2..8 step 2) {
        print(i)
    }
    print(" ")

    for (i in 3 downTo 0) {
        print(i)
    }
    print(" ")

    for (c in 'a'..'d') {
        print(c)
    }
    print(" ")

    for (c in 'z' downTo 's' step 2) {
        print(c)
    }
    print(" ")

    val x = 2
    if (x in 1..5) {
        print("x is in range from 1 to 5")
    }
    println()

    if (x !in 6..10) {
        println("x is not in range from 6 to 10")
    }

    val authors = setOf("Shakespeare", "Hemingway", "Twain")
    val writers = setOf("Twain", "Shakespeare", "Hemingway")
    println(authors == writers)
    println(authors === writers)

    println(max(99, -42))
}

fun max(a: Int, b: Int) = if (a > b) a else b

class Animal(val name: String)

class Zoo(private val animals: List<Animal>) {
    operator fun iterator(): Iterator<Animal> {
        return animals.iterator()
    }
}

fun eatACake() = println("Eat a Cake")
fun bakeACake() = println("Bake a Cake")

fun whenAssign(obj: Any): Any {
    val result = when (obj) {
        1 -> "one"
        "Hello" -> "Greeting"
        is Long -> false
        else -> "Unknown"
    }
    return result
}

fun cases(obj: Any) {
    when (obj) {
        1 -> println("One")
        "Hello" -> println("Greeting")
        is Long -> println("Long")
        !is String -> println("Not a string")
        else -> println("Unknown")
    }
}

